/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-07-07     17247       the first version
 */

#include "uart1_service.h"

// UART1 device handle (should be initialized elsewhere)
extern rt_device_t uart1_dev;

/**
 * @brief Calculate checksum for custom protocol frame.
 *        Sum of LEN, CMD, DATA, RESV (if any), modulo 256.
 */
static uint8_t uart1_calc_checksum(const uint8_t *buf, uint8_t len)
{
    uint8_t sum = 0;
    for (uint8_t i = 0; i < len; i++)
        sum += buf[i];
    return sum;
}

/**
 * @brief Send a custom protocol frame via UART1.
 *        See uart1_service.h for protocol details.
 *
 * @param cmd      Command code
 * @param data     Pointer to data buffer (can be NULL if no data)
 * @param data_len Length of data buffer
 */
void uart1_send_frame(uint8_t cmd, const uint8_t *data, uint8_t data_len)
{
    uint8_t frame[UART1_FRAME_MAXLEN];
    uint8_t idx = 0;
    frame[idx++] = UART1_FRAME_HEAD;
    frame[idx++] = 1 + data_len + UART1_RESV_LEN; // LEN = CMD + DATA + RESV
    frame[idx++] = cmd;
    // Copy data
    for (uint8_t i = 0; i < data_len; i++)
        frame[idx++] = data ? data[i] : 0;
    // Reserved bytes (if any)
#if UART1_RESV_LEN > 0
    for (uint8_t i = 0; i < UART1_RESV_LEN; i++)
        frame[idx++] = 0;
#endif
    // Checksum (LEN, CMD, DATA, RESV)
    frame[idx++] = uart1_calc_checksum(&frame[1], frame[1]);
    frame[idx++] = UART1_FRAME_TAIL;
    // Send via UART1
    if (uart1_dev)
        rt_device_write(uart1_dev, 0, frame, idx);
}
